≑ Menu

Bash Shell PS1: 10 Examples to Make Your Linux Prompt like Angelina Jolie

Photo courtesy of f1r3storm85

In the previous article, we discussed about Linux environment variables PS[1-4] and PROMPT_COMMAND. If used effectively, PS1 can provide valuable information right on the command prompt.

In Tomb Raider, Angelina Jolie has all the gadgets and weapons at her finger tips to solve the mystery in style. While the gadget and style of Angelina Jolie is hard to match, at least let us try to make the good old Linux prompt very functional and stylish using the 10 examples provided in this article.

1. Display username, hostname and current working directory in the prompt

The PS1 in this example displays the following three information in the prompt:

  • \u – Username
  • \h – Hostname
  • \w – Full path of the current working directory
-bash-3.2$ export PS1="\u@\h \w> "

ramesh@dev-db ~> cd /etc/mail
ramesh@dev-db /etc/mail>

2. Display current time in the prompt

In the PS1 environment variable, you can directly execute any Linux command, by specifying in the format $(linux_command). In the following example, the command $(date) is executed to display the current time inside the prompt.

ramesh@dev-db ~> export PS1="\u@\h [\$(date +%k:%M:%S)]> "

ramesh@dev-db [11:09:56]>

You can also use \t to display the current time in the hh:mm:ss format as shown below:

ramesh@dev-db ~> export PS1="\u@\h [\t]> "
ramesh@dev-db [12:42:55]>

You can also use \@ to display the current time in 12-hour am/pm format as shown below:

ramesh@dev-db ~> export PS1="[\@] \u@\h> "
[04:12 PM] ramesh@dev-db>

3. Display output of any Linux command in the prompt

You can display output of any Linux command in the prompt. The following example displays three items separated by | (pipe) in the command prompt:

  • \!: The history number of the command
  • \h: hostname
  • $kernel_version: The output of the uname -r command from $kernel_version variable
  • \$?: Status of the last command
ramesh@dev-db ~> kernel_version=$(uname -r)
ramesh@dev-db ~> export PS1="\!|\h|$kernel_version|\$?> "
473|dev-db|2.6.25-14.fc9.i686|0>

4. Change foreground color of the prompt

Display prompt in blue color, along with username, host and current directory information

$ export PS1="\e[0;34m\u@\h \w> \e[m"
[Note: This is for light blue prompt]

$ export PS1="\e[1;34m\u@\h \w> \e[m"
[Note: This is for dark blue prompt]
  • \e[ – Indicates the beginning of color prompt
  • x;ym – Indicates color code. Use the color code values mentioned below.
  • \e[m – indicates the end of color prompt

Color Code Table:

Black 0;30
Blue 0;34
Green 0;32
Cyan 0;36
Red 0;31
Purple 0;35
Brown 0;33
[Note: Replace 0 with 1 for dark color]

Make the color change permanent by adding the following lines to .bash_profile or .bashrc

STARTCOLOR='\e[0;34m';
ENDCOLOR="\e[0m"
export PS1="$STARTCOLOR\u@\h \w> $ENDCOLOR"

5. Change background color of the prompt

Change the background color by specifying \e[{code}m in the PS1 prompt as shown below.

$ export PS1="\e[47m\u@\h \w> \e[m"
[Note: This is for Light Gray background]

Combination of background and foreground

export PS1="\e[0;34m\e[47m\u@\h \w> \e[m"
[Note: This is for Light Blue foreground and Light Gray background]

Add the following to the .bash_profile or .bashrc to make the above background and foreground color permanent.

STARTFGCOLOR='\e[0;34m';
STARTBGCOLOR="\e[47m"
ENDCOLOR="\e[0m"
export PS1="$STARTFGCOLOR$STARTBGCOLOR\u@\h \w> $ENDCOLOR"

Play around by using the following background color and choose the one that suites your taste:

  • \e[40m
  • \e[41m
  • \e[42m
  • \e[43m
  • \e[44m
  • \e[45m
  • \e[46m
  • \e[47m

6. Display multiple colors in the prompt

You can also display multiple colors in the same prompt. Add the following function to .bash_profile

function prompt {
  local BLUE="\[\033[0;34m\]"
  local DARK_BLUE="\[\033[1;34m\]"
  local RED="\[\033[0;31m\]"
  local DARK_RED="\[\033[1;31m\]"
  local NO_COLOR="\[\033[0m\]"
  case $TERM in
    xterm*|rxvt*)
      TITLEBAR='\[\033]0;\u@\h:\w\007\]'
      ;;
    *)
      TITLEBAR=""
      ;;
  esac
  PS1="\u@\h [\t]> "
  PS1="${TITLEBAR}\
  $BLUE\u@\h $RED[\t]>$NO_COLOR "
  PS2='continue-> '
  PS4='$0.$LINENO+ '
}

You can re-login for the changes to take effect or source the .bash_profile as shown below.

$. ./.bash_profile
$ prompt
ramesh@dev-db [13:02:13]>

7. Change the prompt color using tput

You can also change color of the PS1 prompt using tput as shown below:

$ export PS1="\[$(tput bold)$(tput setb 4)$(tput setaf 7)\]\u@\h:\w $ \[$(tput sgr0)\]"

tput Color Capabilities:

  • tput setab [1-7] – Set a background color using ANSI escape
  • tput setb [1-7] – Set a background color
  • tput setaf [1-7] – Set a foreground color using ANSI escape
  • tput setf [1-7] – Set a foreground color

tput Text Mode Capabilities:

  • tput bold – Set bold mode
  • tput dim – turn on half-bright mode
  • tput smul – begin underline mode
  • tput rmul – exit underline mode
  • tput rev – Turn on reverse mode
  • tput smso – Enter standout mode (bold on rxvt)
  • tput rmso – Exit standout mode
  • tput sgr0 – Turn off all attributes

Color Code for tput:

  • 0 – Black
  • 1 – Red
  • 2 – Green
  • 3 – Yellow
  • 4 – Blue
  • 5 – Magenta
  • 6 – Cyan
  • 7 – White

8. Create your own prompt using the available codes for PS1 variable

Use the following codes and create your own personal PS1 Linux prompt that is functional and suites your taste. Which code from this list will be very helpful for daily use? Leave your comment and let me know what PS1 code you’ve used for your Linux prompt.

  • \a an ASCII bell character (07)
  • \d the date in “Weekday Month Date” format (e.g., “Tue May 26”)
  • \D{format} – the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required
  • \e an ASCII escape character (033)
  • \h the hostname up to the first part
  • \H the hostname
  • \j the number of jobs currently managed by the shell
  • \l the basename of the shell’s terminal device name
  • \n newline
  • \r carriage return
  • \s the name of the shell, the basename of $0 (the portion following the final slash)
  • \t the current time in 24-hour HH:MM:SS format
  • \T the current time in 12-hour HH:MM:SS format
  • \@ the current time in 12-hour am/pm format
  • \A the current time in 24-hour HH:MM format
  • \u the username of the current user
  • \v the version of bash (e.g., 2.00)
  • \V the release of bash, version + patch level (e.g., 2.00.0)
  • \w the current working directory, with $HOME abbreviated with a tilde
  • \W the basename of the current working directory, with $HOME abbreviated with a tilde
  • \! the history number of this command
  • \# the command number of this command
  • \$ if the effective UID is 0, a #, otherwise a $
  • \nnn the character corresponding to the octal number nnn
  • \\ a backslash
  • \[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
  • \] end a sequence of non-printing character

9. Use bash shell function inside PS1 variable

You can also invoke a bash shell function in the PS1 as shown below.

ramesh@dev-db ~> function httpdcount {
>  ps aux | grep httpd | grep -v grep | wc -l
> }

ramesh@dev-db ~> export PS1="\u@\h [`httpdcount`]> "
ramesh@dev-db [12]>
[Note: This displays the total number of running httpd processes]

You can add the following line to .bash_profile or .bashrc to make this change permanent:

function httpdcount {
  ps aux | grep httpd | grep -v grep | wc -l
}
export PS1='\u@\h [`httpdcount`]> '

10. Use shell script inside PS1 variable

You can also invoke a shell script inside the PS1 variable. In the example below, the ~/bin/totalfilesize.sh, which calculates the total filesize of the current directory, is invoked inside the PS1 variable.

ramesh@dev-db ~> cat ~/bin/totalfilesize.sh

for filesize in $(ls -l . | grep "^-" | awk '{print $5}')
do
  let totalsize=$totalsize+$filesize
done
echo -n "$totalsize"

ramesh@dev-db ~> export PATH=$PATH:~/bin
ramesh@dev-db ~> export PS1="\u@\h [\$(totalfilesize.sh) bytes]> "
ramesh@dev-db [534 bytes]> cd /etc/mail
ramesh@dev-db [167997 bytes]>
[Note: This executes the totalfilesize.sh to display the total
       file size of the current directory in the PS1 prompt]


How much customization have you done to your PS1? Can your PS1 beat Angelina Jolie? Leave a comment and share your PS1 prompt value.

Recommended Reading

Bash Cookbook, by Carl Albing, JP Vossen and Cameron Newham. Bash is a very powerful shell. This book will help you to master the bash shell and become highly productive. Whether you are a sysadmin, DBA or a developer, you have to write shell script at some point. A wise sysadmin knows that once you’ve mastered the shell-scripting techniques, you can put your servers on auto-pilot mode by letting the shell-scripts do the grunt work. To get to the auto-pilot mode of sysadmin, you definitely need to master the examples provided in this cookbook. There are quiet few Bash shell books out there. But, this books tops them all by giving lot of detailed examples.
 
Additional Linux book recommendation: 12 Amazing and Essential Linux Books To Enrich Your Brain and Library
 
If you liked this article, please bookmark it on del.icio.us and Stumble it.

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • LKeeper September 12, 2008, 8:55 am

    Ad 7: using so much external commands is ineffective. During PS1 evaluation (after every command) it will run so much tputs… Using direct color setting is MUCH MORE efficient.

    Ad 9 and 10… $(…) and `…` are same

    Ad 8 and before: \[33[ is same as \e[ which is much shorter to write, and makes scripts more compact…

    Basicly instead of all 10 examples we could have only 2: 8th and 9th…

  • Neil Cherry September 12, 2008, 9:45 am

    While not as fancy as some of the prompts above here’s one I’ve been using for years:

    TTYNAME=`tty|cut -b 6-`
    export PS1=”\[33[01;34m\][\w]\n\[33[01;31m\]\u@\h\[33[01;34m\]($TTYNAME)$ \[33[00m\]”

    Which looks like this:

    [~/website/misc/Coffee]
    ncherry@cookie(pts/0)$

    The nice thing about it is that the \w (path) doesn’t move the prompt position where you start typing. The TTYNAME is important because I always run more than one shell, sometimes on more than one box. This just helps to minimize the confusion.

  • Gavin Flower September 12, 2008, 4:01 pm

    Thanks, my new system prompt is:

    PS1=”\e[1;36m\$(date +%a.%H%m%S)\e[m # ”

    I often wondered when I last issued a yum update, or some such…

  • Doug September 12, 2008, 4:31 pm

    Hi,

    Nice, straight-forward, clear article.

    I’d just like to point out that I once worked with one of the authors of SimCity… and he had
    quite a unique prompt style which actually made great sense. His prompt always started with
    a ‘#’ and ended with a new-line e.g.

    # ramesh@dev-db [12:42:55]
    echo
    # ramesh@dev-db [12:43:15]
    ls -ltr

    The great thing about this, once your eyes got used to it, was you could then just copy and
    paste great swathes of previous commands (or just a single line) as perfect shell scripts.

    Combined with the old double click and triple click selection mode this was very nice indeed.

    Anyway, just thought I’d share his unique take on shell prompts with the rest of you.

    Cheers,

    Doug

  • nkuitse September 13, 2008, 8:39 am

    My multi-line bash prompt:
    PS1=’\[\e[1;32m\]\u@\h `smiley` \[\e[0;32m\]\w\[\e[0m\]\n\$ ‘
    smiley ()
    {
    if [ $? = 0 ]; then
    echo -e ‘\e[32m:)\e[0m’;
    true;
    else
    echo -e ‘\e[31m:(\e[0m’;
    return $?;
    fi
    }
    Adapted from someone else’s code (forgot who or where).

  • Ramesh September 13, 2008, 12:15 pm

    @LKeeper,

    Yes. I agree. Using direct colors inside the PS1 prompt is probably efficient than using multiple tput’s in PS1.

    @Doug,

    Very nice idea to begin the prompt with #. I like the idea of copying the multiple lines from prompt and using it in a shell script (or) just pasting it to execute the commands again.

    @Neil, Gavin, nkuitse,

    Thanks for sharing your PS1.

  • Alejandro Moreno September 15, 2008, 12:07 pm

    Nice. I like the idea of having the time in the prompt. Right now I only have the user@host + current folder, because I didn’t like my prompt to shrink and grow too much while “browsing” for files in the terminal, but with Doug’s suggestion, I think I’ll change mine to:

    PS1=”# \u@\h [\t] \w>\n”

    for something like:

    # self@linuxbox [15:34:03] /home/self>
    man bash

    πŸ˜‰

  • Aaron September 16, 2008, 5:31 pm

    This is great, thank you for sharing.

  • MrSpider October 31, 2008, 4:53 pm

    Here is my one:
    PS1=”\e[0;34m#\e[m \u@\h[\W]\n\e[0;34m#\e[m >”;
    It’s also with a new line πŸ˜‰

    And for the ones who like lost:
    alias ‘4’=’echo “You are a Lostfreak πŸ˜‰ – You know the magic numbers:4″‘;

  • Sam November 5, 2008, 11:40 pm

    Handy post! I would have loved this years ago, when I first tried to figure out how to color my prompt:-) In the vein of sharing, my current prompt is:

    PS1=”\[33[0;31m\][\T]\[33[0;36m\]\u@\[33[1;33m\]\H \[33[1;34m\]\w: \[33[0m\]”

    For me, this is easiest to read, see where I am, copy into a file for easy logging with datestamps, etc.

    I also came across a neat little script to view what all the colors and backgrounds look like on a console, which makes it easier to pick what works for you. More details here: http://dancingpenguinsoflight.com/2007/10/reference-script-for-cli-color-codes/

  • Ked December 10, 2008, 5:34 pm

    Hi,

    Can you tell me how to get rid of the Tilde “~” which is displayed instead of my home directory?

    Someone suggested using $PWD but it simply displays my home directory no matter which directory I change to (ie the new directory is not displayed on the fly).

    Thanks,

  • ces December 18, 2008, 1:46 pm

    @Ked

    That tilde is supposed to stand for your home directory, actually. Not sure where this tradition came from, and I’m not sure how to change it, but it’s a “feature” of the bash shell. You can do “cd ~” to change into your home directory. “cd ~-” will cause you to go to the last directory you were in.

  • mo February 9, 2009, 9:45 am

    so you want us to make our command prompts fugly?

  • Angelo February 20, 2009, 10:04 am

    A correction to the %k:%m:%S format suggested: %m is for month, not minutes (at least the current version, maybe long ago it was different).

    It should be %k:%M:%S (or %H:%M:%S, as you prefer).

  • Mike O March 30, 2009, 10:50 am

    Answer to your question:

    PS1=”my PS1 > Angelina Jolie # “

  • Quinn Taylor April 6, 2009, 5:32 pm

    When setting prompt colors (whether with tputs or directly) be sure to put \[ and \] around the change. If you leave it off, poor bash gets confused about where your line should wrap, and strange things start to happen.

    For example, the following modifications are equivalent, but the latter eliminates strange behaviors:

    $ export PS1=”\e[0;34m\u@\h \w> \e[m”
    $ export PS1=”\[\e[0;34m\]\u@\h \w> \[\e[m\]”

    Thanks for the post, it was handy!

  • Ramesh April 11, 2009, 12:44 am

    @Alejandro, MrSpider, Sam,

    Thanks for sharing your PS1 prompt.
     

    @Ked,

    Like ces pointed out, \w or \W in a PS1 will always display ~ for the home directory instead of expanding it. I don’t think there is any way to change that.
     

    @Angelo,

    Thanks a lot for pointing it out. I’ve corrected it. %m is for month. %M is for minutes. I’ve changed the prompt mentioned in #2 to the following.

    # export PS1="\u@\h [\$(date +%k:%M:%S)]> "
    

     

    @Quinn,

    Thanks for the suggestions. On my system, it worked properly even without enclosing the PS1 without the \[ and \]. I’ll definitely remember your suggestion, when I get into trouble, if it doesn’t work.

  • Dominique Michel April 12, 2009, 10:43 am

    Thank you all ! And especially Ramesh, LKeeper and Doug !

    It was very funny to play with $PS1. Here is the result for now, I think that my one line PS1 is worth sharing:

    export PS1=”\e[01;33m# \e[01;35m`date +’%A %d %B %Y, %X %Z(%:::z)’` \e[00;31m\u\e[01;32m@\e[00;31m\]\h \e[01;33m\w :\e[00m\n”

    It show a # (cool!), the localized date and time with the timezone, as well than the user’s name and location. I put ” :” at the end of the line in order to be in agreement with my locale. Last is a line return.

  • agn July 6, 2009, 6:20 am

    You can avoid ‘ps aux | grep httpd | grep -v grep’ by using ‘ps aux | grep [h]ttpd’ .

  • Ramesh Natarajan July 8, 2009, 10:33 pm

    @Dominique Michel,

    I agree with you. Doug’s idea is awesome and excellent out-of-the-box thinking. Thanks for sharing your cool PS1 prompt with us.

    @Agn,

    Excellent. It works great. I always had the habit of using grep -v in that situation. I should start changing my habit and use [ ] in the grep. Thanks for sharing it with us.

  • Dominique Michel July 8, 2009, 11:37 pm

    @Ramesh Nataraja

    I made some bug changes. The first version is not updating the date when the time is running, this one will do it:

    export PS1=”\e[01;33m# \e[01;35m\D{%A %e %B %G %R %Z} \e[00;31m\u\e[01;32m@\e[00;31m\h \e[01;33m\w :\e[00m\n”

  • abe January 13, 2010, 8:44 am

    I like almost every post I’ve ever seen. Well done.

  • Ilyas February 15, 2010, 11:00 am

    What if I want to get the real time with t. Something same like tick tock of the clock, everyone second, minute should be displayed in real time.

  • longshot February 23, 2010, 9:26 am

    I like setting the title bar in my prompt so it shows where I’m logged in and in what directory. I use a function to set my multi-line prompt with:

    function bash_prompt
    {
    local TITLEBAR=’\[\e]0;\u@\h:\w07\]’
    local TEXT=”\[\e[1;36m\]”
    local RED=”\[\e[0;31m\]”
    local DEF=”\[\e[0;37m\]”
    local NONE=”\[\e[0m\]”

    PS1=”${TITLEBAR}\n\
    ${DEF}[${TEXT}\d${DEF}@${TEXT}\T${DEF}]\n\
    ${DEF}{${TEXT}\u${DEF}@${TEXT}\h${DEF}}\n\
    ${DEF}\n\
    ${DEF}(${RED}jobs:\j/\!${DEF}|${RED}cmd#:\!${DEF}|${RED}\\\$?:\$?${DEF}) \$${NONE} ”
    }

  • Benjamin Lu April 22, 2010, 6:25 pm

    1). Put the line below to /etc/profile, save it:
    export PS1=”(`date`) 33[33m\]\n[\e[1;36;40m\u@\e[1;31;40m\H:\e[1;33;40m\w]\e[1;0m\nbash$ ”
    2). after re-login, your system will show time stamp in one line in ( ), the next line will show full path with userid@full_hostname:working_dir_in_fullpath in [ ].
    (Thu Apr 22 16:39:55 PDT 2010)
    [your_userid@your_host.com:~]
    3). in the example above, I set the color Blue for userid, Red for hostname, and orange for working dirs. You can have diff colors by changing colo code in the example.

    Good Luck

    Ben

  • switchfox1977 April 28, 2010, 5:36 am

    My environment uses GMT time and not Local time, so i had to do a little math in order to get the hours to be correct. I know it is not elegant and i will have to change the -4 to a -5 here soon, but hey, it works for me. I put the following into my .bashrc file:
    export a=”$(( `date +%k` -4 ))”; export PS1='($(date +$a:%M:%S)) [\u@\h\w]\$ ‘

    And it ends up looking like this afterwards:
    (7:33:34) [username@hostname~]$

  • Raghu July 12, 2010, 6:10 pm

    Do you all know about the PROMPT_DIRTRIM environment variable for bash? It is a nifty little thing! You set the variable to a number and \w in your PS1 will be expanded to have those many elements. It’s a great way to keep your prompt from growing too long. Here’s an example:

    $ PS1=”\w \$ ”
    ~ $ PROMPT_DIRTRIM=3
    ~ $ cd /usr/share/doc
    /usr/share/doc $ cd xpdf-common
    …/share/doc/xpdf-common $ cd examples
    …/doc/xpdf-common/examples $

    See how \w is expanded?

    (I use Debian sid with bash 4.1.5(1)-release as of this writing.)

  • Habitual August 14, 2010, 10:13 pm

    I hope this doesn’t strip code here. πŸ™‚

    MKF=’This is my Kung-Fu’
    DOS=’C:${PWD//\//\\\}>’
    STAMP=`date “+[%A, %B %d %Y]”`

    PS1=”\[33[01;39m\]$STAMP\n\[33[00m\]\[33[01;31m\]$MKF\n\[33[00m\]\[33[01;39m\]$DOS\[33[00m\]” # My Custom DOS prompt.

  • K Friday October 26, 2010, 9:01 am

    Thanks for #10

  • Jabba Laci February 8, 2011, 6:59 pm

    Just for fun, I wanted to emulate the MS-DOS prompt:

    function msdos_pwd {
    echo `pwd` | tr ‘/’ ‘\\’
    }

    export PS1=’C:`msdos_pwd`> ‘

  • Atul March 2, 2011, 3:01 pm

    Hello,
    I have a strange error when I try to set PS1. I use
    PS1=”\h:\w $ ”
    because I want the host followed by the current working directory. But the prompt I get is:
    h:w$

    How do I correct this?

  • Anonymous March 9, 2011, 8:49 am

    #————————————————————-
    # GIT on Prompt
    #————————————————————-
    function _git_color_status()
    {
    status=”`git status –porcelain 2>/dev/null`”

    #not a git repository
    if [ $? -ne 0 ]; then
    echo -ne $darkgray
    elif [ `echo “$status” | grep “M” | wc -l` != “0” ]; then
    echo -ne $red
    elif [ `echo “$status” | grep “A” | wc -l` != “0” ]; then
    echo -ne $yellow
    elif [ `echo “$status” | grep “??” | wc -l` != “0” ]; then
    echo -ne $cyan
    else
    echo -ne $HILIT2
    fi
    }

    function gitmode()
    {
    if [ -z $1 ] ; then
    return
    fi
    if [ $1 = ‘on’ -a -z “$OLD_PS1″ ]; then
    alias pull=’git pull’
    alias push=’git push’
    alias commit=’git commit -a’
    alias add=’git add’
    #git aliased to git-publish -> push current branch` to origin and then track
    alias publish=’git publish’
    alias status=’git status’
    OLD_PS1=”$PS1″
    PS1=”\[\$(_git_color_status)\][GIT] $PS1”
    unset PREFIX
    elif [ $1 = ‘off’ -a -n “$OLD_PS1″ ]; then
    unalias pull 2> /dev/null
    unalias push 2> /dev/null
    unalias commit 2> /dev/null
    unalias add 2> /dev/null
    unalias publish 2> /dev/null
    unalias status 2> /dev/null
    PS1=”$OLD_PS1”
    unset OLD_PS1
    fi
    }

  • Jim May 19, 2011, 12:39 pm

    I’m liking the examples! Here’s a possible way to get the prompt to list the home directory in the “/home/username” format instead of a tilde (~):

    curdir(){
    if [ $PWD == /home/$USER ]
    then
    echo -n /home/$USER
    else
    echo -n $PWD
    fi
    }

    PS1=”\u@\h \$(curdir)>”

  • Jim May 19, 2011, 1:26 pm

    On reflection, it looks as though something as simple as this works:

    PS1=”\u@\h \$(echo -n \$PWD)>”

  • Jim May 20, 2011, 9:45 am

    Sorry for the multiple posts, but I now realize that the only thing needed to accomplish this is to include a backslash before the $PWD. This ensures that the current working directory is determined each time the prompt is created; without the backslash it would be determined just once and would never change.

    PS1=”\u@\h \$PWD>”

  • Shane September 14, 2011, 10:10 pm

    For years now I’ve been using something like
    PS1=”\`if [ \$? != 0 ]; then echo \[\e[33m\]—=== \[\e[31m\]Oh noes, bad command \[\e[33m\]===—; else echo \e[33m\]#Yay, comamnd succeeded\[\e[0m\]; fi\`\n\n\[\e[0;37m\]#\[\e[1;34m\]xX \[\e[1;32m\]Company Inc. \[\e[1;34m\]Xx\n\[\e[0;37m\]#[\[\e[1;34m\]\w\[\e[0;37m\]]\[\e[0;37m\][\[\e[1;31m\]\j\[\e[0;37m\]][\[\e[1;35m\]\A\[\e[0;37m\]]\[\e[0;37m\][\[\e[0;32m\]\!\[\e[0;37m\]]\[\e[0;37m\][\[\e[1;32m\]\#\[\e[0;37m\]]\n\[\e[0;37m\]#\[\e[0;32m\]\u@\H \[\e[1;31m\]\$ \n ”

    Which gives me something like:

    #xX Company Inc. Xx
    #[~][0][23:58][507][6]
    #User@Host $

    The top is a vanity header, the bottom is pretty much your standard User@Host.All commands start at the next line, which when paired with the leading hashes, helps make for easy script copying, as mentioned before. The second line is really where I get all the info I need. It breaks down as:

    #[Working directly][Number of jobs in background][Time in 24H format][History of command][History of command for this session]

    Also, if the command succeeds, I get a “#Yay, comamnd succeeded” – if it fails, I get the “—=== Oh noes, bad command ===—” message.

  • Alex December 1, 2011, 9:48 am

    It’d be nice to note in (9) that export PS1=”\u@\h [`httpdcount`]> ” would render the httpdcount *when the window is opened* while export PS1=”\u@\h [\`httpdcount\`]> ” would render an updated httpdcount each time a prompt is rendered.

    I’m using
    export PS1=”\h:\`pwd | sed ‘s/^.*\(\/.*\/.*\)$/\1/’\`$ ” to display the most recent 2 directories.

  • liming xing December 26, 2011, 12:06 am

    Hello:
    Excuse me, how do I get in shell file PS1 variables

  • Anonymous December 26, 2011, 2:28 pm

    @ liming xing
    Read ‘man bash’. It is explained into the FILES section, at the end.
    It is ~/.bash_profile or ~/.bashrc.

  • Jake March 17, 2012, 2:23 pm

    Cool

  • Big_Papa April 7, 2012, 7:27 am

    Nice tips,

    This is what I’m using:

    PS1=’\e[0;31m[$(date +%k:%M:%S)]\e[0;36m\u@\e[1;33m\h:\e[1;34m\w\e[0m\$ ‘

    # If this is an xterm set the title to user@host:dir (FROM UBUNTU .bashrc)
    case “$TERM” in
    xterm*|rxvt*)
    PS1=”\[\e]0;\u@\h: \w\a\]$PS1″
    ;;
    *)
    ;;
    esac

    Command Prompt: [15:23:50]root@horst:/etc#
    Title of Terminal: root@horst: /etc

  • Anonymous June 12, 2012, 9:19 pm

    This is my version, tested in cygwin. Put this in .bash_profile

    GREEN=”0;32″
    CYAN=”0;36″
    YELLOW=”1;33″
    GREEN_START=”\[33[${GREEN}m\]”
    CYAN_START=”\[33[${CYAN}m\]”
    YELLOW_START=”\[33[${YELLOW}m\]”
    ORIG_COLOR_START=”\[33[0m\]”
    NEW_LINE=”\n”
    TIME=”\@”
    NOW=”`date +’%b-%d-%Y %r’`”
    PS1=”${NEW_LINE}${CYAN_START}[${NOW}] ${GREEN_START}${USER}@${HOSTNAME} ${YELLOW_START}${PWD}${NEW_LINE}${ORIG_COLOR_START}$ ”

    It works like this, starts with empty line then current date, username, hostname and current working directory with some colors.

    [Jun-12-2012 11:13:39 PM] joh@nrx-2501 /home/joh
    $

  • FreePalestine August 8, 2012, 5:22 pm

    Hi there,
    Just to say Hello and thanks for your article on Bash Shell PS1.
    Keep on sharing my friend,
    A reader from Morocco πŸ™‚

  • Thomas October 13, 2012, 11:46 pm

    Nice !

    I have been using for a long time this PS1 (looks quite well on black background):
    export PS1=’\n\[\e[1;33m\]\u@\H:\[\e[0m\]\[\e[1;36m\]\w\[\e[0m\]\n\[\e[1;50m\]\t->\[\e[0m\]’

    After reading your post, I have revamped it and created little utility that prints the error code if (and only if) the previous shell command failed. (Repeatadely typing ‘echo $?’ could be very tiresome)
    Note that declarations of the variables are ‘local’ – that is because I use it in a custom bash_setup {} function.

    # Styles — err is red, errcode is red bold
    local STYLE_ERR=\[33[0;31m\]
    local STYLE_ERRCODE=\[33[1;31m\]

    # Condition to print the errorcode before the next prompt – it is intended to be included into the $PS1 variable as a prefix.
    # Example: PS1=”$PROMPT_ERRCODE_INCLUDE$YOUR_PROMPT_DEF”
    local PROMPT_ERRCODE_INCLUDE=”\`ERRCODE=\$?; if [[ \$ERRCODE != 0 ]]; then echo \”\n$STYLE_ERR\\\\\\\$? = $STYLE_ERRCODE\$ERRCODE\\n \”; fi\`”

    I have also created a version of this error checking to the ‘commented’ version of prompt that has been shown here – all lines are also commented out with ‘#’ πŸ˜‰
    local SHARP_PROMPT_ERRCODE_INCLUDE=”\`ERRCODE=\$?; if [[ \$ERRCODE != 0 ]]; then echo \”$STYLE_ERR# \\n# \\\\\\\$? = $STYLE_ERRCODE\$ERRCODE$STYLE_ERR\\n# \”; fi\`”

    Note that both are designed the way that $YOUR_PROMPT_DEF begins with newline (\n).

    Hope that helps πŸ™‚

  • rafi February 28, 2013, 3:34 am

    time stamp is done like that as well
    export PS1=”[\t]$PS1″

  • Kippetje March 16, 2013, 6:36 am

    My prompt looks like this now:
    C:\>_
    Thanx for this great article!

  • Lew March 19, 2013, 3:16 pm

    I really like this one that I found somewhere above here:
    export PS1=”#\u@ [\t] \w>\n”
    which comes out like:
    #ludo@ [21:26:45] ~> (and goes to a new line)
    But to make it permanent, in .bashrc I can’t find where to put the “n” (which is for the “new line” I believe). Anyone who does know?

    All I found so far is the right place for the added # (just after PS1=”)
    Here’s how the line in my .bashrc looks now:

    # If this is an xterm set the title to user@host:dir
    case “$TERM” in
    xterm*|rxvt*)
    PS1=”#\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1″

  • Olivier MenguΓ© (dolmen) May 20, 2013, 8:05 am

    @Jabba Laci:

    A more efficient DOS-style prompt simulation for bash:
    PS1=’C:${PWD//\//\\}>’

  • John D. Rowell June 6, 2013, 5:19 am

    OK here’s my take after reading all of the comments:

    `ERRCODE=$?; if [[ $ERRCODE == 0 ]]; then echo “\[33[0;34m\]\[33[44m\]#\[33[1;37m\]$(date +%d/%m/%y\ %H:%M:%S) “; else echo “\[33[0;31m\]\[33[41m\]#\[33[1;37m\]$(date +%d/%m/%y\ %H:%M:%S) \[33[1;31m\]\[33[41m\][\[33[1;33m\]\[33[41m\]$ERRCODE\[33[1;31m\]\[33[41m\]] “; fi`\[33[0;32m\] \w \[33[1;34m\]\u@\h\[33[0;35m\](pts/4)\[33[0m\]\n

    Used the # trick for copy/pasting, _but_ using the same foreground and background colors, so you don’t see it πŸ˜‰ The date usually has a blue background, but when an error occurs it turns red and adds the error code.

  • christopher barry June 7, 2013, 8:55 pm

    I developed a bash function called face, which is a 216-color echo command that can output either color text to the screen or generate PS1 codes for assigning to your prompt. It does foreground and background, and also has a low color mode, for the linux console. Another function, prompt, is a theme-able prompt framework that uses face in the backend to generate all of the escape codes. get it here. If you try it, drop me a note with comments.

  • jaime lira June 8, 2013, 12:17 am

    i got this:
    export PS1=”\\
    $(uname -n): [$(whoami)] [“‘${PWD}'”]\\
    \!> ”
    export PS2=”\\
    $(uname -n): [$(whoami)] [“‘${PWD}'”]\\
    \!> “

  • Lazarus78 August 6, 2013, 11:05 am

    Ive been using this propt for a while. Its simple and provides the information I need.

    PS1=”\e[32m\$PWD\e[0m\n[\u@\h] $> ”

    Which looks like:

    /home/lazarus
    [lazarus@raspberrypi] $>

    The file path is in green as I have it against a dark gray background (#020202) and it makes it easy for me when scrolling through my history to spot where I have types in commands.

  • Anonymous March 24, 2015, 11:35 pm

    for multiple line PS1(with \n), there is an issue for me, I’m using set -o vi mode ,with j k to scroll historical command line, but with multiple line PS1, the historical command might overlap …

  • Jeff July 21, 2015, 10:06 am

    Ok, I’ve got a simple prompt, color scheme and that is as I want it. Problem is after a couple commands, the console somehow gets a char sent that changes the background after the text. How do I make the prompt/color concrete solid (no prompting, no color changes, etc.)?

  • DSpider October 6, 2015, 4:19 pm

    The contents of my ~/.bashrc
    PS1=”\n $ ”

    The contents of my /etc/bash.bashrc (along with a few other simple aliases):
    PS1=”\n # ”

    With this if you run ‘$ su – your_username’, it turns into a “#”, so that you know you’re logged in as root. Simple. Efficient.

  • Jeroen October 23, 2015, 8:11 am

    # Git prompt
    RED=”33[0;31m”
    YELLOW=”\[33[0;33m\]”
    GREEN=”33[0;32m”
    NO_COLOR=”\[33[0m\]”

    function parse_git_branch () {
    VAR=`git status 2>/dev/null`
    if [ $? == 0 ]
    then
    COLOR=”$RED”
    echo ${VAR} | tail | grep “nothing to commit” > /dev/null
    if [ $? == 0 ]
    then
    COLOR=”$GREEN”
    fi
    fi
    echo -n -e “$COLOR”
    git branch 2> /dev/null | sed -e ‘/^[^*]/d’ -e ‘s/* \(.*\)/ (\1)/’
    }

    PS1=”[$GREEN\u@\h$NO_COLOR:\w\$(parse_git_branch)$NO_COLOR]# “

  • Lena December 19, 2015, 12:59 pm

    that’s my super-duper over 5 lines long bash prompt with lots of color

    ##################################################################################
    ##################################################################################
    ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
    ##################################################################################
    ##################################################################################
     #                                                                              #
     # Bash Design                                                                  #
     #                                                                              #
    ##################################################################################
    ##################################################################################
    ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
    ##################################################################################
    ##################################################################################
    
    ### In this section:
    ###  => 256 color support is enabled
    ###  => a super-duper fancy and dynamic bash prompt is created (over 5 lines with lots of info in it)
    ###           Γ— requires at least 80 columns to work
    ###           Γ— design continues at $PS2 to match the end of $PS1
    ###           Γ— the first line is always empty (newline) ─ in case last program forgets to insert a newline to avoid "uglyness"
    ###           Γ— colored and matching $PS3 in case a shell script uses 'select' without setting $PS3 internally
    ###        ─ the info of $PS1 ─
    ###           Γ— users fullname from /etc/passwd
    ###           Γ— machines hostname
    ###           Γ— bash version
    ###           Γ— current time (not updated dynamically ─ bash limitation)
    ###           Γ— last exit status or signal name if it was a signal
    ###           Γ— number of inodes in current working directory (excluding hidden ones .*)
    ###           Γ— current working directory (dynamically formated, like bold slash and nice line wrapping)
    ###           Γ— additional message of last exit code if it was a signal or bash builtin
    ###           Γ— support for custom messages (last command + exit status)
    ###           Γ— current running and stopped stops
    ###           Γ— terminal type and number, example: tty1, tty2 for VT and pts/1, pts/2 for graphical terminals
    ###           Γ— input prompt in its own line
    ###  => a super-duper fancy and dynamic xtrace ($PS4) line is created (full color and informative)
    ###           Γ— more than 150 columns are highly recommended!
    ###  => other color specific things, like GCC_COLORS
    
    ...
    
    # Write last command to file
    function bashrc_write_lastcommand() {
        # Has minor issues with custom $PROMPT_COMMAND, need to add them here ;(
        if [[ "$BASH_COMMAND" != "history -a" && \
              "$BASH_COMMAND" != "history -c" && \
              "$BASH_COMMAND" != "history -r" ]]; then
            local LSTCMD="$BASH_COMMAND" # need this line,
                                         # because $BASH_COMMAND is already updated if you take a look at the next line
                                         # for security issues only store the command itself without its arguments
            printf "%s" "$(echo "$LSTCMD" | awk '{print $1}')" > "$BASHRC_TMPFS/lstcmd"
            LSTCMD=""
        fi
        
        # for performance reasons add to end of file: trap bashrc_write_lastcommand DEBUG
        touch "$BASHRC_TMPFS/lstcmd"
    }
    
    # Works togheter with 'bashrc_get_exitcode', prints custom messages depending on last command and exit status
    function bashrc_extended_description_util() {
        local EXIT=$(< "$BASHRC_TMPFS/exitcode")
        local LSTCMD=$( "$BASHRC_TMPFS/exitcode"
      elif [ "$1" == "description" ]; then
        EXIT=$(< "$BASHRC_TMPFS/exitcode")
        
        if   (( $EXIT == 126 )); then echo -e "\e[0;34m$BASHSIG_EXEC\e[0m";    # 126 BASH: exec error
        elif (( $EXIT == 127 )); then echo -e "\e[0;34m$BASHSIG_CNF\e[0m";     # 127 BASH: command not found
        elif (( $EXIT == 128 )); then echo -e "\e[0;34m$BASHSIG_EXIT\e[0m";    # 128 BAHS: invalid argument to exit
        
        # *NIX (POSIX, BSD, ANSI) Signals found on most common Unix-like operating systems
        elif (( $EXIT == 129 )); then echo -e "$SIGHUP";       # 129 n=1  SIGHUP  (hangup)
        elif (( $EXIT == 130 )); then echo -e "$SIGINT";       # 130 n=2  SIGINT  (interupt)
        elif (( $EXIT == 131 )); then echo -e "$SIGQUIT";      # 131 n=3  SIGQUIT (quit and core dump)
        elif (( $EXIT == 132 )); then echo -e "$SIGILL";       # 132 n=4  SIGILL  (illegal instruction)
        elif (( $EXIT == 133 )); then echo -e "$SIGTRAP";      # 133 n=5  SIGTRAP (trace/breakpoint trap)
        elif (( $EXIT == 134 )); then echo -e "$SIGABRT";      # 134 n=6  SIGABRT (abort)
        elif (( $EXIT == 135 )); then echo -e "$SIGBUS";       # 135 n=7  SIGBUS  (bus error)
        elif (( $EXIT == 136 )); then echo -e "$SIGFPE";       # 136 n=8  SIGFPE  (erroneous arithmetic operation)
        elif (( $EXIT == 137 )); then echo -e "$SIGKILL";      # 137 n=9  SIGKILL (killed)
        elif (( $EXIT == 138 )); then echo -e "$SIGUSR1";      # 138 n=10 SIGUSR1 (user defined signal 1)
        elif (( $EXIT == 139 )); then echo -e "$SIGSEGV";      # 139 n=11 SIGSEGV (segmentation fault)
        elif (( $EXIT == 140 )); then echo -e "$SIGUSR2";      # 140 n=12 SIGUSR2 (user defined signal 2)
        elif (( $EXIT == 141 )); then echo -e "$SIGPIPE";      # 141 n=13 SIGPIPE (broken pipe)
        elif (( $EXIT == 142 )); then echo -e "$SIGALRM";      # 142 n=14 SIGALRM (alarm clock)
        elif (( $EXIT == 143 )); then echo -e "$SIGTERM";      # 143 n=15 SIGTERM (termination)
        elif (( $EXIT == 144 )); then echo -e "$SIGSTKFLT";    # 144 n=16 SIGSTKFLT (stack fault)
        elif (( $EXIT == 145 )); then echo -e "$SIGCHLD";      # 145 n=17 SIGCHLD (child stopped or exited)
        elif (( $EXIT == 146 )); then echo -e "$SIGCONT";      # 146 n=18 SIGCONT (continue execution SIGSTOP)
        elif (( $EXIT == 147 )); then echo -e "$SIGSTOP";      # 147 n=19 SIGSTOP (stop execution)
        elif (( $EXIT == 148 )); then echo -e "$SIGTSTP";      # 148 n=20 SIGTSTP (terminal stop)
        elif (( $EXIT == 149 )); then echo -e "$SIGTTIN";      # 149 n=21 SIGTTIN (bg process trying to read tty)
        elif (( $EXIT == 150 )); then echo -e "$SIGTTOU";      # 150 n=22 SIGTTOU (bg process trying to write tty)
        elif (( $EXIT == 151 )); then echo -e "$SIGURG";       # 151 n=23 SIGURG  (urgent condition on socket)
        elif (( $EXIT == 152 )); then echo -e "$SIGXCPU";      # 152 n=24 SIGXCPU (cpu limit exceeded)
        elif (( $EXIT == 153 )); then echo -e "$SIGXFSZ";      # 153 n=25 SIGXFSZ (file size limit exceeded)
        elif (( $EXIT == 154 )); then echo -e "$SIGVTALRM"     # 154 n=26 SIGVTALRM (virtual timer expired)
        elif (( $EXIT == 155 )); then echo -e "$SIGPROF"       # 155 n=27 SIGPROF (profiling timer expired)
        elif (( $EXIT == 156 )); then echo -e "$SIGWINCH";     # 156 n=28 SIGWINCH (window size change)
        elif (( $EXIT == 157 )); then echo -e "$SIGIO";        # 157 n=29 SIGIO   (I/O now possible)
        elif (( $EXIT == 158 )); then echo -e "$SIGPWR";       # 158 n=30 SIGPWR  (power failure)
        else bashrc_extended_description_util;
        fi
      elif [ "$1" == "description-size" ]; then
        EXIT=$(< "$BASHRC_TMPFS/exitcode")
        
        if   (( $EXIT == 126 )); then echo "${#BASHSIG_EXEC}"; # 126 BASH: exec error
        elif (( $EXIT == 127 )); then echo "${#BASHSIG_CNF}";  # 127 BASH: command not found
        elif (( $EXIT == 128 )); then echo "${#BASHSIG_EXIT}"; # 128 BAHS: invalid argument to exit
        
        # *NIX (POSIX, BSD, ANSI) Signals found on most common Unix-like operating systems
        elif (( $EXIT == 129 )); then echo "${#SIGHUP}";       # 129 n=1  SIGHUP  (hangup)
        elif (( $EXIT == 130 )); then echo "${#SIGINT}";       # 130 n=2  SIGINT  (interupt)
        elif (( $EXIT == 131 )); then echo "${#SIGQUIT}";      # 131 n=3  SIGQUIT (quit and core dump)
        elif (( $EXIT == 132 )); then echo "${#SIGILL}";       # 132 n=4  SIGILL  (illegal instruction)
        elif (( $EXIT == 133 )); then echo "${#SIGTRAP}";      # 133 n=5  SIGTRAP (trace/breakpoint trap)
        elif (( $EXIT == 134 )); then echo "${#SIGABRT}";      # 134 n=6  SIGABRT (abort)
        elif (( $EXIT == 135 )); then echo "${#SIGBUS}";       # 135 n=7  SIGBUS  (bus error)
        elif (( $EXIT == 136 )); then echo "${#SIGFPE}";       # 136 n=8  SIGFPE  (erroneous arithmetic operation)
        elif (( $EXIT == 137 )); then echo "${#SIGKILL}";      # 137 n=9  SIGKILL (killed)
        elif (( $EXIT == 138 )); then echo "${#SIGUSR1}";      # 138 n=10 SIGUSR1 (user defined signal 1)
        elif (( $EXIT == 139 )); then echo "${#SIGSEGV}";      # 139 n=11 SIGSEGV (segmentation fault)
        elif (( $EXIT == 140 )); then echo "${#SIGUSR2}";      # 140 n=12 SIGUSR2 (user defined signal 2)
        elif (( $EXIT == 141 )); then echo "${#SIGPIPE}";      # 141 n=13 SIGPIPE (broken pipe)
        elif (( $EXIT == 142 )); then echo "${#SIGALRM}";      # 142 n=14 SIGALRM (alarm clock)
        elif (( $EXIT == 143 )); then echo "${#SIGTERM}";      # 143 n=15 SIGTERM (termination)
        elif (( $EXIT == 144 )); then echo "${#SIGSTKFLT}";    # 144 n=16 SIGSTKFLT (stack fault)
        elif (( $EXIT == 145 )); then echo "${#SIGCHLD}";      # 145 n=17 SIGCHLD (child stopped or exited)
        elif (( $EXIT == 146 )); then echo "${#SIGCONT}";      # 146 n=18 SIGCONT (continue execution SIGSTOP)
        elif (( $EXIT == 147 )); then echo "${#SIGSTOP}";      # 147 n=19 SIGSTOP (stop execution)
        elif (( $EXIT == 148 )); then echo "${#SIGTSTP}";      # 148 n=20 SIGTSTP (terminal stop)
        elif (( $EXIT == 149 )); then echo "${#SIGTTIN}";      # 149 n=21 SIGTTIN (bg process trying to read tty)
        elif (( $EXIT == 150 )); then echo "${#SIGTTOU}";      # 150 n=22 SIGTTOU (bg process trying to write tty)
        elif (( $EXIT == 151 )); then echo "${#SIGURG}";       # 151 n=23 SIGURG  (urgent condition on socket)
        elif (( $EXIT == 152 )); then echo "${#SIGXCPU}";      # 152 n=24 SIGXCPU (cpu limit exceeded)
        elif (( $EXIT == 153 )); then echo "${#SIGXFSZ}";      # 153 n=25 SIGXFSZ (file size limit exceeded)
        elif (( $EXIT == 154 )); then echo "${#SIGVTALRM}";    # 154 n=26 SIGVTALRM (virtual timer expired)
        elif (( $EXIT == 155 )); then echo "${#SIGPROF}";      # 155 n=27 SIGPROF (profiling timer expired)
        elif (( $EXIT == 156 )); then echo "${#SIGWINCH}";     # 156 n=28 SIGWINCH (window size change)
        elif (( $EXIT == 157 )); then echo "${#SIGIO}";        # 157 n=29 SIGIO   (I/O now possible)
        elif (( $EXIT == 158 )); then echo "${#SIGPWR}";       # 158 n=30 SIGPWR  (power failure)
        else bashrc_extended_description_util size;
        fi
      else
        EXIT=$( success
        elif (( $EXIT >  0   && $EXIT  error
        elif (( $EXIT == 126 )); then                  echo -e "\e[0;44m\e[97mEXEC\e[0m";  # 126      blue -> EXEC error
        elif (( $EXIT == 127 )); then                  echo -e "\e[0;44m\e[97mCNF\e[0m";   # 127      blue -> CNF error
        elif (( $EXIT == 128 )); then                  echo -e "\e[0;44m\e[97mEXIT\e[0m";  # 128      blue -> EXIT error
        
        # *NIX (POSIX, BSD, ANSI) Signals found on most common Unix-like operating systems
        elif (( $EXIT == 129 )); then       echo -e "\e[0;35mSIGHUP\e[0m";       # 129 n=1  SIGHUP  (hangup)
        elif (( $EXIT == 130 )); then echo -e "\e[0;45m\e[97mSIGINT\e[0m";       # 130 n=2  SIGINT  (interupt)
        elif (( $EXIT == 131 )); then       echo -e "\e[0;35mSIGQUIT\e[0m";      # 131 n=3  SIGQUIT (quit and core dump)
        elif (( $EXIT == 132 )); then echo -e "\e[0;41m\e[97mSIGILL\e[0m";       # 132 n=4  SIGILL  (illegal instruction)
        elif (( $EXIT == 133 )); then       echo -e "\e[0;35mSIGTRAP\e[0m";      # 133 n=5  SIGTRAP (trace/breakpoint trap)
        elif (( $EXIT == 134 )); then       echo -e "\e[0;35mSIGABRT\e[0m";      # 134 n=6  SIGABRT (abort)
        elif (( $EXIT == 135 )); then       echo -e "\e[0;35mSIGBUS\e[0m";       # 135 n=7  SIGBUS  (bus error)
        elif (( $EXIT == 136 )); then echo -e "\e[0;41m\e[97mSIGFPE\e[0m";       # 136 n=8  SIGFPE  (erroneous arithmetic operation)
        elif (( $EXIT == 137 )); then echo -e "\e[0;45m\e[97mSIGKILL\e[0m";      # 137 n=9  SIGKILL (killed)
        elif (( $EXIT == 138 )); then echo -e "\e[0;46m\e[97mSIGUSR1\e[0m";      # 138 n=10 SIGUSR1 (user defined signal 1)
        elif (( $EXIT == 139 )); then echo -e "\e[0;41m\e[97mSIGSEGV\e[0m";      # 139 n=11 SIGSEGV (segmentation fault)
        elif (( $EXIT == 140 )); then echo -e "\e[0;46m\e[97mSIGUSR2\e[0m";      # 140 n=12 SIGUSR2 (user defined signal 2)
        elif (( $EXIT == 141 )); then       echo -e "\e[0;35mSIGPIPE\e[0m";      # 141 n=13 SIGPIPE (broken pipe)
        elif (( $EXIT == 142 )); then       echo -e "\e[0;35mSIGALRM\e[0m";      # 142 n=14 SIGALRM (alarm clock)
        elif (( $EXIT == 143 )); then echo -e "\e[0;45m\e[97mSIGTERM\e[0m";      # 143 n=15 SIGTERM (termination)
        elif (( $EXIT == 144 )); then echo -e "\e[0;41m\e[97mSIGSTKFLT\e[0m";    # 144 n=16 SIGSTKFLT (stack fault)
        elif (( $EXIT == 145 )); then       echo -e "\e[0;35mSIGCHLD\e[0m";      # 145 n=17 SIGCHLD (child stopped or exited)
        elif (( $EXIT == 146 )); then echo -e "\e[0;44m\e[97mSIGCONT\e[0m";      # 146 n=18 SIGCONT (continue execution SIGSTOP)
        elif (( $EXIT == 147 )); then echo -e "\e[0;44m\e[97mSIGSTOP\e[0m";      # 147 n=19 SIGSTOP (stop execution)
        elif (( $EXIT == 148 )); then echo -e "\e[0;44m\e[97mSIGTSTP\e[0m";      # 148 n=20 SIGTSTP (terminal stop)
        elif (( $EXIT == 149 )); then echo -e "\e[0;44m\e[97mSIGTTIN\e[0m";      # 149 n=21 SIGTTIN (bg process trying to read tty)
        elif (( $EXIT == 150 )); then echo -e "\e[0;44m\e[97mSIGTTOU\e[0m";      # 150 n=22 SIGTTOU (bg process trying to write tty)
        elif (( $EXIT == 151 )); then       echo -e "\e[0;35mSIGURG\e[0m";       # 151 n=23 SIGURG  (urgent condition on socket)
        elif (( $EXIT == 152 )); then echo -e "\e[0;43m\e[97mSIGXCPU\e[0m";      # 152 n=24 SIGXCPU (cpu limit exceeded)
        elif (( $EXIT == 153 )); then echo -e "\e[0;43m\e[97mSIGXFSZ\e[0m";      # 153 n=25 SIGXFSZ (file size limit exceeded)
        elif (( $EXIT == 154 )); then echo -e "\e[0;43m\e[97mSIGVTALRM\e[0m"     # 154 n=26 SIGVTALRM (virtual timer expired)
        elif (( $EXIT == 155 )); then echo -e "\e[0;43m\e[97mSIGPROF\e[0m"       # 155 n=27 SIGPROF (profiling timer expired)
        elif (( $EXIT == 156 )); then       echo -e "\e[0;35mSIGWINCH\e[0m";     # 156 n=28 SIGWINCH (window size change)
        elif (( $EXIT == 157 )); then echo -e "\e[0;40m\e[97mSIGIO\e[0m";        # 157 n=29 SIGIO   (I/O now possible)
        elif (( $EXIT == 158 )); then echo -e "\e[1;41m\e[97mSIGPWR\e[0m"        # 158 n=30 SIGPWR  (power failure)
        
        elif (( $EXIT >  158 && $EXIT  error
        elif (( $EXIT == 255 )); then                  echo -e "\e[1;31m$EXIT\e[0m"; # 255      red (bold) -> exit status exceed
        else                                           echo            "$EXIT";      # *        black [just in case]
        fi
      fi
    }
    
    # Get current system time in format HH:MM:SS
    function bashrc_get_currenttime() {
      date +"%T"
    }
    
    # Get jobs currently running and stopped ─ contains length of string for separator function
    function bashrc_get_jobscount() {
       local stopped="$(jobs -s | wc -l | tr -d " ")"
       local running="$(jobs -r | wc -l | tr -d " ")"
       local jobs_string="${running}r/${stopped}s"
       local jobs_strsize="${#jobs_string}"
       if [ "$1" == "strsize" ]; then echo "$jobs_strsize"
       else echo "$jobs_string"
       fi
    }
    
    # Inserts a separator of $1, optimal: substrate $2 number to fill the rest of the line
    function bashrc_insert_separator() {
      # define local variables
      local fillsize=""
      local fill=""
      # check if $1 exists, if not set it to space
      local fillchar=${1:-" "}
      # check if $2 exists, if not set it to 0
      local minusfill=${2:-"0"}
      # calculate fillsize
      let fillsize=$(($(tput cols) - $minusfill))
      # insert separator
      if [ "$fillchar" == " " ]; then printf '%*s\n' "${fillsize}" ''
      else
        while [ "$fillsize" -gt "0" ]; do
            fill="$fillchar${fill}"
            let fillsize=${fillsize}-1
        done
        # print separator
        echo $fill
      fi
    }
    
    # This function prints the current working directory on screen, but with some little extras
    #  -- respect terminal columns and enters a newline instead of the ugly line wrapping
    #  -- don't trim in middle of file or folder name if no space left
    #     makes it easier to see the directory tree
    #     if for some reason the file/folder name is longer than the terminal columns, the name is wrapped into a new line
    #  -- perfect for fancy dynamic bash prompts
    #
    #  Usage: $0 [int-extra-indentation-for-firstline]
    #            (-16)
    function bashrc_pretty_print_pwd() {
        # every possible new line starts with this (except the first one)
        local newline_starter="# | "
        
        # every possible line ends with this (including first one)
        local newline_ender="  "
    
        # calculate available space
        local columns_firstline=$(($(tput cols) - ${#newline_ender} - $1))
        local columns=$(($columns_firstline - ${#newline_starter}))
        
        # store 'pwd' into an array, split at directory indicator '/'
        local pwd="$(pwd)"
        pwd="${pwd/$HOME/\~}" # replace $HOME path with tilde
        IFS='/' read -r -a pwd <<< "$pwd"
        [ -z "${pwd[0]}" ] && pwd=("${pwd[@]:1}")
        
        # create output buffer (contains escape sequences)
        local outbuf
        
        # append first '/' if not starts with tilde~
        [ "${pwd[0]}" != "~" ] && outbuf+="/"
        
        # TODO 
        for i in "${pwd[@]}"; do
            outbuf+="${i}/"
        done
        
        # finalize string ─ bold the directory indicator '/'
        if (( ${#outbuf} != 1 )); then outbuf="${outbuf::-1}"; fi
        outbuf="$(echo "$outbuf" | sed 's/\//\\e\[1m\/\\e\[0m/g')"
        outbuf="$(echo "$outbuf" | sed 's/~/\\e[90m~\\e[0m/1')"
        echo -e -n "$outbuf"
    }
    
    ##################################################################################
    # PS1 ─ User Input                                                               #
    ##################################################################################
    
    # executed only once per session ─ this code greps the full username from the /etc/passwd file
    # -- workaround for a 'all-lowercase-username', Redhed-based distros doesn't have this issue
    # -- personally I prefer a free usernaming like Redhed-based distros does
    PASSWD_CURRENT_USER_FULLNAME="$(awk -F":" '{ print $1$5 }' /etc/passwd | grep $(whoami) | sed "s/^$(whoami)//")"
    
    # executed only once per session ─ this code generates the header line (along with its size for the separator function)
    BASHRC_USERHOSTNAME="$PASSWD_CURRENT_USER_FULLNAME@\[$(tput bold && tput setaf 1)\]\h\[$(tput sgr0)\]"
    BASHRC_USERHOSTNAME_SIZE="$PASSWD_CURRENT_USER_FULLNAME@$(hostname)"
    BASHRC_USERHOSTNAME_SIZE=${#BASHRC_USERHOSTNAME_SIZE}
    BASHRC_LOCALTIME_SIZE="$(bashrc_get_currenttime)"
    BASHRC_LOCALTIME_SIZE=${#BASHRC_LOCALTIME_SIZE}
    BASHRC_BASH_VERSION_STRING="$(tput bold && tput setaf 5)GNU/Bash:$(tput sgr0) $BASH_VERSION"
    BASHRC_BASH_VERSION_SIZE=${#BASHRC_BASH_VERSION_STRING}
    PS1_HEADER_SIZE=$(($BASHRC_USERHOSTNAME_SIZE + $BASHRC_LOCALTIME_SIZE + $BASHRC_BASH_VERSION_SIZE + 3))
    unset BASHRC_USERHOSTNAME_SIZE
    unset BASHRC_LOCALTIME_SIZE
    unset BASHRC_BASH_VERSION_SIZE
    
    BASHRC_TERMINAL="$(tty | sed 's/^\/dev\///')"
    BASHRC_TERMINAL_SIZE=${#BASHRC_TERMINAL}
    
    # executed each time when a command finished
    PS1_HEADER="# -- ${BASHRC_USERHOSTNAME} -\$(bashrc_insert_separator - $PS1_HEADER_SIZE)- ${BASHRC_BASH_VERSION_STRING} ---- \$(bashrc_get_currenttime)\n"
    PS1_MAINLINE="# [\$(bashrc_get_exitcode)] CWD[\$(ls | wc -l)]: \$(bashrc_pretty_print_pwd 15)\n"
    PS1_INFOLINE="# \$(bashrc_get_exitcode description) \$(bashrc_insert_separator \" \" \$((\$(bashrc_get_jobscount strsize) + $BASHRC_TERMINAL_SIZE + 30 + \$(bashrc_get_exitcode description-size)))) [$(tput bold && tput setaf 4)Jobs:$(tput sgr0) \$(bashrc_get_jobscount)] [$(tput setaf 5)Terminal:$(tput sgr0) ${BASHRC_TERMINAL}]\n"
    PS1_CMDINPUT="# > "
    
    PS1="\$(bashrc_get_exitcode set)$(tput sgr0)\n${PS1_HEADER}${PS1_MAINLINE}${PS1_INFOLINE}${PS1_CMDINPUT}"
    
    ##################################################################################
    # PS2 ─ Wait for more User Input (multiline)                                 (\) #
    ##################################################################################
    PS2="#   "
    
    ##################################################################################
    # PS3 ─ select prompt     [in case there is no one set internally in the script] #
    ##################################################################################
    export PS3="# $(tput bold)[select]$(tput sgr0) > "
    
    ##################################################################################
    # PS4 ─ Script Debugging                                                (xtrace) #
    ##################################################################################
    # # $script_name@line[$LINENO] > $function(): $line_content
    export PS4="# \e[38;5;239m(xtrace)\e[0m \e[4m\e[90m\$(basename \"\${BASH_SOURCE}\")\e[39m@\e[3mline\e[1m[\${LINENO}]\e[24m \e[1;34m>\e[0m \e[38;5;105m\${FUNCNAME[0]}()\e[0m: "
    
  • Eve Hawkins May 6, 2016, 3:31 am

    OMG, why can’t the command prompt be pink! I want it to be pink!!!